package com.example.dbmeta.meta.common.xml;

import com.example.dbmeta.exception.DbMetaBootException;
import com.example.dbmeta.exception.DbMetaErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import static com.example.dbmeta.exception.DbMetaErrorCode.CONFIG_PARSE_ERROR;
import static com.example.dbmeta.exception.ErrorCode.FILE_NOT_FOUND;
import static com.example.dbmeta.exception.ErrorCode.PARASCOPE_ERROR;

@Service
@Slf4j
public class XmlConfigLoader {


    private void validateConfiguration(XmlConfig xmlConfig) {
        // 验证保留天数
        Integer keepdays = xmlConfig.getKeepdays();
        if (keepdays == null || keepdays < 1 || keepdays > 60) {
            //throw new DbMetaBootException(PARASCOPE_ERROR,"config.xml","keepdays 必须在1-60之间，当前值: " + keepdays,"检查系统环境或联系支持人员");
            throw new DbMetaBootException(
                    DbMetaErrorCode.INVALID_KEEPDAYS,
                    "keepdays值" + keepdays + "不在允许范围内(1-60)", // 错误详情
                    "请修改配置中的<keepdays>值为有效范围",        // 建议修复方案
                    1, 60, keepdays                            // 参数值
            );
        }

        // 验证源数据源
        List<DataInstance> dataInstances = xmlConfig.getDataInstances();
        ConfigValidator.validateDataInstances(dataInstances);

        // 验证目标数据源
        DestinationDataSource destDataSource = xmlConfig.getDestinationDataSource();
        ConfigValidator.validateDestination(destDataSource);
    }

    public XmlConfig loadDataInstancesFromXml(String filePath) throws Exception {
//        File configFile = resolveConfigFile(filePath);
//
//        log.info("加载配置文件位置: " + configFile.getAbsolutePath()); // 添加调试输出
//        System.out.println("加载配置文件位置: " + configFile.getAbsolutePath());

        ApplicationHome home = new ApplicationHome(getClass());
        File jarDir = home.getSource().getParentFile();

        // 如果未传入路径，使用默认配置文件
        if (filePath == null || filePath.isEmpty()) {
            filePath = "config.xml";
        }

        File configFile = new File(jarDir, filePath);
        System.out.println("加载配置文件路径: " + configFile.getAbsolutePath());

        if (!configFile.exists()) {
            throw new Exception("配置文件未找到: " + configFile.getAbsolutePath());
        }

        try (InputStream is = new FileInputStream(configFile)) {
            JAXBContext jaxbContext = JAXBContext.newInstance(Configurations.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            Configurations configurations = (Configurations) unmarshaller.unmarshal(is);

            XmlConfig xmlConfig = new XmlConfig();
            xmlConfig.setSourceDataSource(configurations.getSourceDataSource());
            xmlConfig.setDataInstances(configurations.getSourceDataSource().getDataInstances());

            xmlConfig.setDestinationDataSource(configurations.getDestinationDataSource());
            xmlConfig.setKeepdays(configurations.getKeepdays());
            // 3. 验证配置
            validateConfiguration(xmlConfig);
            return xmlConfig;
        } catch (DbMetaBootException dbMetaBootException) {
            throw dbMetaBootException;
        } catch (Exception e) {
            //throw new DbMetaBootException("配置文件加载失败: ");
            System.out.println(e);
            throw new DbMetaBootException(CONFIG_PARSE_ERROR, "config.xml", e.getMessage(), "检查系统环境或联系支持人员");

        }
    }

    private File resolveConfigFile(String filePath) throws FileNotFoundException, URISyntaxException {
        if (isAbsolutePath(filePath)) {
            return new File(filePath);
        }

        // 获取JAR所在目录 (兼容IDE和JAR运行)
        File jarDir = getJarDirectory();
        return new File(jarDir, filePath);
    }
    // 判断是否为绝对路径
    private boolean isAbsolutePath(String path) {
        if (path == null || path.isEmpty()) return false;

        // Windows路径 (如 C:\...)
        if (path.length() > 2 && path.charAt(1) == ':') return true;

        // Unix路径 (如 /usr/...)
        return path.startsWith("/");
    }
    // 健壮的JAR目录获取方法
    private File getJarDirectory() throws URISyntaxException {
        URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
        File sourceLocation = new File(location.toURI());

        // 如果是JAR文件，返回所在目录
        if (sourceLocation.isFile()) {
            return sourceLocation.getParentFile();
        }

        // 如果是目录 (IDE运行)，返回target/classes目录
        return sourceLocation;
    }
}
